/****************************************************************************
*
*                            Open Watcom Project
*
* Copyright (c) 2002-2020 The Open Watcom Contributors. All Rights Reserved.
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Convertor from binary format file to C source code, for
*                assembly code bursts.
*
****************************************************************************/


/* This program is used to link against an assembly file containing
   code bursts for inline pragmas.  The information from the assembly
   is output to either codei86.gh (16-bit) or code386.gh (32-bit).
   This allows us to use an assembler to translate the code bursts into
   the appropriate byte sequences. This program convert binary file
   generated by assembler and linker to appropriate C source code.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define BUFSIZE     4096

#define Xptr(x)     (buff + x)

struct bursts {
    unsigned short defs;
    unsigned short name;
    unsigned short burst;
};

int main(int argc, char *argv[])
{
    FILE                *fp;
    int                 i;
    int                 len;
    char                *p;
    struct bursts       *cb;
    char                *buff;
    size_t              size;
    size_t              read_size;
    int                 opt_bytes;

    opt_bytes = 0;
    i = 1;
    if( argc > 1 ) {
        p = argv[1];
        if( p[0] == '-' || p[0] == '/' ) {
            opt_bytes = ( p[1] == 'b' || p[1] == 'B' );
            argc--;
            i++;
        }
    }
    if( argc < 3 ) {
        printf( "Usage: [-b] inp.file out.file\n" );
        return( 1 );
    }
    fp = fopen( argv[i], "rb" );
    if( fp == NULL ) {
        printf( "Error: Can not open input file.\n" );
        return( 1 );
    }
    size = 0;
    buff = NULL;
    for( ;; ) {
        buff = realloc( buff, size + BUFSIZE );
        read_size = fread( buff + size, 1, BUFSIZE, fp );
        if( read_size < BUFSIZE ) {
            size += read_size;
            break;
        }
        size += BUFSIZE;
    }
    if( ferror( fp ) ) {
        fclose( fp );
        free( buff );
        printf( "Error: can not read inp.file\n" );
        return( 1 );
    }
    fclose( fp );
    fp = fopen( argv[i + 1], "wt" );
    if( fp == NULL ) {
        free( buff );
        printf( "Error: can not open out.file\n" );
        return( 1 );
    }
    if( opt_bytes ) {
        p = buff;
        i = 0;
        while( size-- > 0 ) {
            fprintf( fp, "0x%2.2X,", (unsigned char)*p++ );
            i++;
            if( i == 16 ) {
                fprintf( fp, "\n" );
                i = 0;
            }
        }
        if( i ) {
            fprintf( fp, "\n" );
        }
    } else {
        cb = (struct bursts *)Xptr( *(unsigned short *)buff );
        for( ;; ) {
            p = Xptr( cb->defs );
            if( p == buff )
                break;
            for( ;; ) {
                fprintf( fp, "%s\n", p );
                while( *p != '\0' )
                    ++p;
                ++p;
                if( *p == '\0' ) {
                    break;
                }
            }
            p = Xptr( cb->burst );
            len = (unsigned char)*p++;
            fprintf( fp, "static struct STRUCT_BYTE_SEQ( %d ) %s = { %d, false, {\n    ", len, Xptr( cb->name ), len );
            i = 0;
            for( ;; ) {
                fprintf( fp, "0x%2.2X", (unsigned char)*p++ );
                --len;
                if( len == 0 )
                    break;
                fprintf( fp, "," );
                i++;
                if( i == 10 ) {
                    fprintf( fp, "\n    " );
                    i = 0;
                }
            }
            fprintf( fp, "\n} };\n\n" );
            cb++;
        }
    }
    fclose( fp );
    free( buff );
    return( 0 );
}
